#include "Camera.h"
#include "ui_Camera.h"
#include <QCameraInfo>
#include <QCameraImageCapture>
#include <QVideoFrame>
#include <QMessageBox>
#include <QFile>
#include <QUrl>

Camera::Camera(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Camera)
{
    ui->setupUi(this);
    QList<QCameraInfo> cameras = QCameraInfo::availableCameras() ;
    if (cameras.size()>0){

        ui->actStartCamera->setEnabled(true);
        ui->actStopCamera->setDisabled(true);
        iniCamera(); //初始化摄像头
        iniImageCapture() ;//初始化静态抓图
        iniVideoRecorder() ;//初始化视频录制
        curCamera->start() ;
    }
    else
    {
        ui->actStartCamera->setDisabled(true);
        ui->actStopCamera->setDisabled(true);
        ui->actCapture->setDisabled(true);
        ui->actVideoRecord->setDisabled(true);
        ui->actVideoStop->setDisabled(true);
    }
}

Camera::~Camera()
{
    delete ui;
}

void Camera::onCameraStateChanged(QCamera::State state)
{

    switch (state){
    case QCamera:: UnloadedState:
        ui->LabCameraState->setText ("摄像头state: UnloadedState") ;
        break;
    case QCamera:: LoadedState:
        ui->LabCameraState->setText ("摄像头state: LoadedState") ;
        break;
    case QCamera::ActiveState:
        ui->LabCameraState->setText ("摄像头state: ActiveState") ;
    }
    ui ->actStartCamera->setEnabled (state!=QCamera::ActiveState);
    ui ->actStopCamera->setEnabled (state==QCamera::ActiveState);
}

void Camera::onCameraCaptureModeChanged(QCamera::CaptureModes mode)
{

    if (mode==QCamera::CaptureStillImage)
        ui->LabCameraMode->setText ("抓取模式: StillImage") ;
    else if (mode==QCamera::CaptureVideo)
        ui->LabCameraMode->setText ("抓取模式: Video") ;
    else
        ui->LabCameraMode->setText ("抓取模式: Viewfinder") ;
}

void Camera::onImageReadyForCapture(bool ready)
{
    //可以抓图 了
    ui->actCapture->setEnabled(ready) ;
}

void Camera::onImageCaptured(int id, const QImage &preview)
{
    //抓取图片后显示
    Q_UNUSED(id);

    QImage scaledImage = preview.scaled (ui->LabCapturedImage->size(), Qt::KeepAspectRatio, Qt::SmoothTransformation);
    ui->LabCapturedImage->setPixmap(QPixmap::fromImage(scaledImage));

}

void Camera::onImageSaved(int id, const QString &fileName)
{
    //文件保存后显示保存的文件名
    Q_UNUSED(id) ;
    qInfo()<<"onImageSaved ="<<fileName;
    ui->editOutputFile->setText(fileName);
    // LabInfo->setText ("图片保存为:"+fileName) ;
}

void Camera::onVideoStateChanged(QMediaRecorder::State state)
{
    //状态变化
    ui->actVideoRecord->setEnabled (state!=QMediaRecorder::RecordingState);
    ui->actVideoStop->setEnabled (state==QMediaRecorder::RecordingState);
}

void Camera::onVideoDurationChanged(qint64 duration)
{
    ui->LabDuration->setText(QString ("录制时间:%1秒") .arg (duration/1000) ) ;
}

void Camera::iniCamera()
{
    // 创建QCamera对象
    QCameraInfo curCameraInfo=QCameraInfo::defaultCamera(); //获取缺省 摄像头
    ui->comboCamera->addItem(curCameraInfo.description());
    ui->comboCamera->setCurrentIndex (0) ;

    curCamera=new QCamera (curCameraInfo, this); //创建摄像头对象

    curCamera->setViewfinder(ui->viewFinder); //设置 预览框
    curCamera->setCaptureMode(QCamera::CaptureViewfinder) ;
    //判断摄像头是否支持抓图、录制视频
    ui->checkStillImage->setChecked(curCamera->isCaptureModeSupported (QCamera::CaptureStillImage)) ; //抓图
    ui ->checkVideo->setChecked (curCamera->isCaptureModeSupported (QCamera::CaptureVideo)) ;//视频录制

    connect (curCamera, SIGNAL (stateChanged (QCamera: :State)),this, SLOT (onCameraStateChanged(QCamera::State)));
    //Windows平台上不支持captureModeChanged()信号
    connect (curCamera, SIGNAL(captureModeChanged(QCamera::CaptureModes)), this, SLOT (onCameraCaptureModeChanged(QCamera::CaptureModes))) ;
}

void Camera::iniImageCapture()
{
    //创建QCameraImageCapture对象
    imageCapture = new QCameraImageCapture(curCamera, this) ;
    imageCapture->setBufferFormat(QVideoFrame::Format_Jpeg); //缓冲区格式
    imageCapture->setCaptureDestination (QCameraImageCapture::CaptureToFile); //保存目标
    connect (imageCapture, SIGNAL (readyForCaptureChanged (bool)),this, SLOT (onImageReadyForCapture (bool) ) ) ;
    connect (imageCapture, SIGNAL (imageCaptured(int, const QImage &)) ,  this, SLOT (onImageCaptured(int, const QImage &))) ;
    connect (imageCapture, SIGNAL (imageSaved(int, const QString &)) ,   this, SLOT (onImageSaved(int, const QString &))) ;
}

void Camera::iniVideoRecorder()
{
    //创建QMediaRecorder对象
    mediaRecorder = new QMediaRecorder(curCamera, this) ;
    ui->chkMute->setChecked (mediaRecorder->isMuted() ) ;
    connect (mediaRecorder,SIGNAL (stateChanged(QMediaRecorder::State)) , this, SLOT (onVideoStateChanged(QMediaRecorder::State))) ;
    connect (mediaRecorder, SIGNAL (durationChanged (qint64)) , this, SLOT(onVideoDurationChanged(qint64)));
}


void Camera::on_actStartCamera_clicked()
{
    //开启摄像头
    curCamera->start();
}

void Camera::on_actStopCamera_clicked()
{
    //关闭摄像头
    curCamera->stop();
}

void Camera::on_actCapture_clicked()
{
    //抓图按钮
    if (curCamera->captureMode () !=QCamera::CaptureStillImage){
        curCamera->setCaptureMode (QCamera::CaptureStillImage) ;
    }

    imageCapture->capture() ;
}

void Camera::on_actVideoRecord_clicked()
{
    //开始录像
    if ( !mediaRecorder->isAvailable() )
    {
        QMessageBox::critical (this, "错误",
                               "不支持视频录制! \n mediaRecorder->isAvailable()==false") ;
        return;
    }
    if (curCamera->captureMode () !=QCamera::CaptureVideo)
        curCamera->setCaptureMode (QCamera::CaptureVideo);

    QString selectedFile=ui->editOutputFile->text().trimmed();

    if (selectedFile. isEmpty())
    {
        QMessageBox::critical (this, "错误", "请先设置录音输出文件") ;
        return;
    }
    if (QFile::exists(selectedFile) )
        if (!QFile::remove(selectedFile) )
        {
            QMessageBox::critical (this, "错误", "所设置录音输出文件被占用，无法删除") ;
            return;
        }

    mediaRecorder->setOutputLocation (QUrl::fromLocalFile(selectedFile)) ;
    mediaRecorder->record() ;
}

void Camera::on_actVideoStop_clicked()
{
    //停止录像
  mediaRecorder->stop();
}
